package org.acm.seguin.refactor.type; import org.acm.seguin.parser.ChildrenVisitor; import org.acm.seguin.parser.ast.ASTAllocationExpression; import org.acm.seguin.parser.ast.ASTArguments; import org.acm.seguin.parser.ast.ASTConstructorDeclaration; import org.acm.seguin.parser.ast.ASTMethodDeclaration; import org.acm.seguin.parser.ast.ASTName; import org.acm.seguin.parser.ast.ASTNameList; import org.acm.seguin.parser.ast.ASTPrimaryExpression; import org.acm.seguin.parser.ast.ASTPrimaryPrefix; import org.acm.seguin.parser.ast.ASTPrimarySuffix; import org.acm.seguin.parser.ast.ASTType; import org.acm.seguin.parser.ast.ASTUnmodifiedClassDeclaration; import org.acm.seguin.parser.ast.ASTUnmodifiedInterfaceDeclaration; import org.acm.seguin.summary.TypeSummary; import org.acm.seguin.summary.query.ContainsStatic; /** * Scan through the abstract syntax tree and replace types with a new value. * *@author Chris Seguin *@created September 10, 1999 */ public class RenameTypeVisitor extends ChildrenVisitor { /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTUnmodifiedClassDeclaration node, Object data) { RenameTypeData rtd = (RenameTypeData) data; if (rtd.getOld().getNameSize() == 1) { String oldName = rtd.getOld().getName(); if (oldName.equals(node.getName())) { String name = rtd.getNew().getName(); node.setName(name); } } int index = 0; if (node.jjtGetChild(index) instanceof ASTName) { if (node.jjtGetChild(index).equals(rtd.getOld())) { node.jjtAddChild(rtd.getNew(), index); } index++; } if (node.jjtGetChild(index) instanceof ASTNameList) { ASTNameList namelist = (ASTNameList) node.jjtGetChild(index); for (int ndx = 0; ndx < namelist.jjtGetNumChildren(); ndx++) { if (namelist.jjtGetChild(ndx).equals(rtd.getOld())) { namelist.jjtAddChild(rtd.getNew(), ndx); } } } return node.childrenAccept(this, data); } /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTUnmodifiedInterfaceDeclaration node, Object data) { RenameTypeData rtd = (RenameTypeData) data; if (rtd.getOld().getNameSize() == 1) { String oldName = rtd.getOld().getName(); if (oldName.equals(node.getName())) { String name = rtd.getNew().getName(); node.setName(name); } } int index = 0; if (node.jjtGetChild(index) instanceof ASTNameList) { ASTNameList namelist = (ASTNameList) node.jjtGetChild(index); for (int ndx = 0; ndx < namelist.jjtGetNumChildren(); ndx++) { if (namelist.jjtGetChild(ndx).equals(rtd.getOld())) { namelist.jjtAddChild(rtd.getNew(), ndx); } } } return node.childrenAccept(this, data); } /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTConstructorDeclaration node, Object data) { RenameTypeData rtd = (RenameTypeData) data; if (rtd.getOld().getNameSize() == 1) { String oldName = rtd.getOld().getName(); if (oldName.equals(node.getName())) { String name = rtd.getNew().getName(); node.setName(name); } } if ((node.jjtGetNumChildren() >= 2) && (node.jjtGetChild(1) instanceof ASTNameList)) { ASTNameList nameList = (ASTNameList) node.jjtGetChild(1); processExceptions(nameList, rtd); } return node.childrenAccept(this, data); } /** * Description of the Method * *@param node Description of Parameter *@param data Description of Parameter *@return Description of the Returned Value */ public Object visit(ASTMethodDeclaration node, Object data) { if ((node.jjtGetNumChildren() >= 3) && (node.jjtGetChild(2) instanceof ASTNameList)) { ASTNameList nameList = (ASTNameList) node.jjtGetChild(2); RenameTypeData rtd = (RenameTypeData) data; processExceptions(nameList, rtd); } return super.visit(node, data); } /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTType node, Object data) { if (node.jjtGetNumChildren() == 0) { return data; } if (node.jjtGetChild(0) instanceof ASTName) { ASTName child = (ASTName) node.jjtGetChild(0); RenameTypeData rtd = (RenameTypeData) data; if (child.equals(rtd.getOld())) { node.jjtAddChild(rtd.getNew(), 0); } else if (child.startsWith(rtd.getOld())) { node.jjtAddChild(child.changeStartingPart(rtd.getOld(), rtd.getNew()), 0); } } return node.childrenAccept(this, data); } /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTPrimaryExpression node, Object data) { ASTPrimaryPrefix prefix = (ASTPrimaryPrefix) node.jjtGetChild(0); if (prefix.jjtGetNumChildren() == 0) { return data; } if (prefix.jjtGetChild(0) instanceof ASTName) { ASTName child = (ASTName) prefix.jjtGetChild(0); RenameTypeData rtd = (RenameTypeData) data; if (child.equals(rtd.getOld())) { prefix.jjtAddChild(rtd.getNew(), 0); } else if (child.startsWith(rtd.getOld())) { if (isStatic(rtd, child, isMethod(node))) { ASTName name = child.changeStartingPart(rtd.getOld(), rtd.getNew()); prefix.jjtAddChild(name, 0); } } } return node.childrenAccept(this, data); } /** * To visit a node * *@param node The node we are visiting *@param data The rename type data *@return The rename type data */ public Object visit(ASTAllocationExpression node, Object data) { if (node.jjtGetNumChildren() == 0) { return data; } if (node.jjtGetChild(0) instanceof ASTName) { ASTName child = (ASTName) node.jjtGetChild(0); RenameTypeData rtd = (RenameTypeData) data; if (child.equals(rtd.getOld())) { node.jjtAddChild(rtd.getNew(), 0); } else if (child.startsWith(rtd.getOld())) { node.jjtAddChild(child.changeStartingPart(rtd.getOld(), rtd.getNew()), 0); } } return node.childrenAccept(this, data); } /** * Determines if the node is a method invocation * *@param node the node in question *@return true when we are looking at a method */ private boolean isMethod(ASTPrimaryExpression node) { if (node.jjtGetNumChildren() <= 1) { return false; } ASTPrimarySuffix suffix = (ASTPrimarySuffix) node.jjtGetChild(1); return (suffix.jjtGetChild(0) instanceof ASTArguments); } /** * Gets the Static attribute of the RenameTypeVisitor object * *@param data Description of Parameter *@param name Description of Parameter *@param isMethod Description of Parameter *@return The Static value */ private boolean isStatic(RenameTypeData data, ASTName name, boolean isMethod) { int last = name.getNameSize(); String value = name.getNamePart(last - 1); TypeSummary typeSummary = data.getTypeSummary(); return ContainsStatic.query(typeSummary, value, isMethod); } /** * Description of the Method * *@param nameList Description of Parameter *@param rtd Description of Parameter */ private void processExceptions(ASTNameList nameList, RenameTypeData rtd) { int last = nameList.jjtGetNumChildren(); for (int ndx = 0; ndx < last; ndx++) { ASTName next = (ASTName) nameList.jjtGetChild(ndx); if (next.equals(rtd.getOld())) { nameList.jjtAddChild(rtd.getNew(), 0); } else if (next.startsWith(rtd.getOld())) { nameList.jjtAddChild(next.changeStartingPart(rtd.getOld(), rtd.getNew()), 0); } } } }